
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UMC.Bridge;
using UMC.Data;
using UMC.ITME.Entities;
using UMC.Net;

namespace UMC.ITME;

class DnsServer
{
    private Socket udpIp4, udpIP6;

    // IPAddress[] _address;
    public static IPAddress[] Addresses
    {
        get; set;
    } = new IPAddress[] { IPAddress.Loopback };//, IPAddress.Parse("127.0.0.2"), IPAddress.Parse("127.0.0.3"), IPAddress.Parse("127.0.0.4") };

    public void Http(object sender, SocketAsyncEventArgs eventArgs)
    {
        do
        {
            var client = eventArgs.AcceptSocket;
            eventArgs.AcceptSocket = null;
            switch (eventArgs.SocketError)
            {
                case SocketError.OperationAborted:
                    return;
                case SocketError.Success:
                    var ip = (client.RemoteEndPoint as IPEndPoint).Address;
                    if (ip.IsIPv4MappedToIPv6)
                    {
                        ip = ip.MapToIPv4();
                    }
                    var ipvalue = new byte[16];
                    if (ip.TryWriteBytes(ipvalue, out var l))
                    {
                        var reId = new StringValue(ipvalue, 0, l);
                        var firewall = DataFactory.Instance().Firewall(reId);
                        switch (firewall?.AuthType)
                        {
                            case Entities.AuthType.Deny:
                                client.Close();
                                client.Dispose();
                                return;
                        }
                        ProcessDnsRequest(client);
                    }
                    break;
            }
        } while (!HttpMimeServier.Accept((Socket)sender, eventArgs));


    }
    public const uint TLSTIME = 10;
    public Socket[] Bind(int port)
    {

        // 设置本地端口
        var _localEndPoint = new IPEndPoint(IPAddress.Any, port);

        udpIp4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        udpIp4.Bind(_localEndPoint);

        var _receiveEventArgs = new SocketAsyncEventArgs();
        _receiveEventArgs.SetBuffer(new byte[512], 0, 512);
        _receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceiveCompleted);

        _receiveEventArgs.RemoteEndPoint = _localEndPoint;

        if (!udpIp4.ReceiveFromAsync(_receiveEventArgs))
        {
            // 如果是同步完成了接收
            OnReceiveCompleted(udpIp4, _receiveEventArgs);
        }
        udpIP6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
        _localEndPoint = new IPEndPoint(IPAddress.IPv6Any, port);
        udpIP6.Bind(_localEndPoint);

        _receiveEventArgs = new SocketAsyncEventArgs();
        _receiveEventArgs.SetBuffer(new byte[512], 0, 512);
        _receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceiveCompleted);

        _receiveEventArgs.RemoteEndPoint = _localEndPoint;

        if (!udpIP6.ReceiveFromAsync(_receiveEventArgs))
        {
            // 如果是同步完成了接收
            OnReceiveCompleted(udpIP6, _receiveEventArgs);
        }
        return new Socket[] { udpIp4, udpIP6 };
    }


    private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
    {
        // 处理接收到的数据
        var udp = (Socket)sender;
        if (e.BytesTransferred > 0)
        {
            ProcessDnsRequest(udp, e.Buffer.AsMemory(0, e.BytesTransferred), (IPEndPoint)e.RemoteEndPoint);

            while (!udp.ReceiveFromAsync(e))
            {
                if (e.BytesTransferred > 0)
                {
                    ProcessDnsRequest(udp, e.Buffer.AsMemory(0, e.BytesTransferred), (IPEndPoint)e.RemoteEndPoint);
                }
                else
                {
                    break;
                }
            }
        }
    }
    private async void ProcessDnsRequest(Socket client)
    {

        // requestData.
        using (client)
        {
            var b = new byte[2];
            await client.ReceiveAsync(new ArraySegment<byte>(b));
            ushort size = System.Buffers.Binary.BinaryPrimitives.ReadUInt16BigEndian(b.AsSpan(0));
            byte[] requestData = System.Buffers.ArrayPool<byte>.Shared.Rent(size + 600);
            int size2 = await client.ReceiveAsync(new ArraySegment<byte>(requestData));

            try
            {
                ushort questionCount = System.Buffers.Binary.BinaryPrimitives.ReadUInt16BigEndian(requestData.AsSpan(4));
                if (questionCount == 0)
                {
                    return;
                }
                var iPEndPoint = (IPEndPoint)client.RemoteEndPoint;
                var address = iPEndPoint.Address;

                var clientId = address.GetAddressBytes();

                // 提取查询的域名 
                StringValue domainName = ParseDomainName(requestData);

                var domains = ParentDomain(domainName);
                if (domainName.Span.EndsWith(Socks5Server.ProxyDomain.Span))
                {

                    var indexs = new Dictionary<uint, bool>();
                    var ms = HotCache.Find(new ProxySite());
                    indexs.Add(0, false);
                    foreach (var m in ms)
                    {
                        var value3 = m.ProxyIP.UInt32() ?? 0;
                        if (value3 != 0)
                        {
                            if (indexs.TryGetValue(value3, out var value33))
                            {
                                if (m.Type.Int32() == 1)
                                {

                                    if (value33 == false)
                                    {
                                        indexs[value3] = true;
                                    }
                                }
                            }
                            else
                            {
                                indexs[value3] = m.Type.Int32() == 1;
                            }
                        }
                    }

                    var proxys = indexs.Keys.ToArray();
                    Array.Sort(proxys);

                    var value = domainName.Slice(0, domainName.Length - Socks5Server.ProxyDomain.Length - 1);
                    if (value.IsEmpty == false)
                    {
                        int v = value.Span.IndexOf((byte)'-');
                        if (v == -1)
                        {
                            v = value.Span.IndexOf((byte)'.');
                        }
                        if (v > -1 && Utility.TryParse(value.Slice(v + 1).Span, 10, out var proxyId))
                        {
                            if (proxyId < proxys.Length && indexs[proxys[proxyId]])
                            {
                                var addreses = new IPAddress[] { new IPAddress(proxys[proxyId].StringValue().Span) };//[ySite.ProxyType.Span) };
                                int size4 = BuildDnsResponse(requestData, domainName, 10, addreses);//BuildDnsResponse(requestData, domainName, 10);
                                b[0] = (byte)((size4 >> 8) & 0xFF);
                                b[1] = (byte)(size4 & 0xFF);

                                await client.SendAsync(new ArraySegment<byte>(b));
                                await client.SendAsync(new ArraySegment<byte>(requestData, 0, size4));
                                return;
                            }
                        }
                    }
                    int size3 = BuildDnsResponse(requestData, domainName, 10);
                    b[0] = (byte)((size3 >> 8) & 0xFF);
                    b[1] = (byte)(size3 & 0xFF);

                    await client.SendAsync(new ArraySegment<byte>(b));
                    await client.SendAsync(new ArraySegment<byte>(requestData, 0, size3));

                    return;
                }

                var proxySite = HotCache.Find(new ProxySite { Domain = domainName }, "Domain", domains).OrderByDescending(d => d.Domain.Length).FirstOrDefault();
                if (proxySite != null)
                {
                    var addreses = Array.Empty<IPAddress>();
                    var ProxyType = proxySite.ProxyIP.UInt32() ?? 0;

                    if (ProxyType != 0 && proxySite.Type.Int32() == 1)
                    {

                        int value = 0;
                        if (proxySite.ProxyIP.Length > 4)
                        {
                            Utility.MD5(domainName.Span, requestData.AsSpan(400));

                            var md5 = Utility.IntParse(requestData.AsSpan(400, 16)).StringValue();
                            var query = proxySite.RecursiveQuery ?? StringValue.Empty;

                            int iplen = proxySite.ProxyIP.Length;
                            if (iplen < query.Length)// >proxySite.ProxyIP.Length)
                            {
                                query = query.Slice(0, iplen);
                            }
                            value = query.Span.IndexOf(md5.Span);
                            if (value == -1)
                            {
                                if (query.Length != iplen)
                                {
                                    if (query.Length < iplen)
                                    {
                                        var t = new byte[query.Length + 4];
                                        query.Span.CopyTo(t);
                                        query = new StringValue(t);
                                    }
                                    else
                                    {
                                        query = query.Slice(0, iplen);
                                    }
                                    md5.Span.CopyTo(query.Span.Slice(query.Length - 4));
                                }
                                else
                                {
                                    query.Span.Slice(4, query.Length - 4).CopyTo(query.Span);
                                    md5.Span.CopyTo(query.Span.Slice(query.Length - 4));
                                }

                                HotCache.Put(new ProxySite
                                {
                                    Domain = proxySite.Domain,
                                    RecursiveQuery = query,//new StringValue(t)
                                });
                                value = ((query.Length - 4) / 4) % (proxySite.ProxyIP.Length / 4);
                            }
                            else
                            {
                                value = (value / 4) % (proxySite.ProxyIP.Length / 4);
                            }
                        }
                        addreses = new IPAddress[] { new IPAddress(proxySite.ProxyIP.Slice(value * 4, 4).Span) };

                    }
                    if (Socks5Server.IsInternalIP(clientId) == false)
                    {
                        var md5 = UMC.Data.Utility.IntParse(UMC.Data.Utility.MD5(clientId));
                        var sockUser = Bridge.SocksUser.Cache.Get(new SocksUser
                        {
                            ClientIP = new StringValue(clientId),
                            UserAgent = md5.StringValue(),
                            Port = ((ushort)443).StringValue()
                        });
                        if (sockUser == null || HttpMimeServier.Current.Handler.Invoke().CheckUser(proxySite.ConfigKey, sockUser.Username, proxySite.Domain) == false)
                        {
                            addreses = await NetProxy.DNSToIPAsync(domainName.UTF8(), new CancellationTokenSource(5000).Token);
                        }

                    }
                    int size3 = BuildDnsResponse(requestData, domainName, TLSTIME, addreses);
                    b[0] = (byte)((size3 >> 8) & 0xFF);
                    b[1] = (byte)(size3 & 0xFF);

                    await client.SendAsync(new ArraySegment<byte>(b));
                    await client.SendAsync(new ArraySegment<byte>(requestData, 0, size3));
                    return;
                }
                var timeOut = new CancellationTokenSource(5000);
                using (UdpClient client2 = new UdpClient(IterativeDNS.AddressFamily))
                {
                    await client2.SendAsync(requestData.AsMemory(0, size), IterativeDNS, timeOut.Token);
                    var res = await client2.ReceiveAsync(timeOut.Token);
                    var size3 = res.Buffer.Length;
                    b[0] = (byte)((size3 >> 8) & 0xFF);
                    b[1] = (byte)(size3 & 0xFF);

                    await client.SendAsync(new ArraySegment<byte>(b));
                    await client.SendAsync(new ArraySegment<byte>(res.Buffer, 0, size3));

                }

            }
            catch
            {

            }
            finally
            {
                System.Buffers.ArrayPool<byte>.Shared.Return(requestData);
            }
        }
    }

    Set<int, IPEndPoint> reposts = new Set<int, IPEndPoint>((x, y) => x.CompareTo(y));
    private async void ProcessDnsRequest(Socket udp, Memory<byte> reques, IPEndPoint clientEndPoint)
    {
        if (reques.Length == 4)
        {
            reposts[System.Buffers.Binary.BinaryPrimitives.ReadInt32BigEndian(reques.Span)] = clientEndPoint;
            return;
        }

        byte[] requestData = System.Buffers.ArrayPool<byte>.Shared.Rent(600);
        int size = reques.Length;
        reques.CopyTo(requestData);


        try
        {

            if (requestData[0] == 0x08 && requestData[size - 1] == 0x00)
            {
                var domain_value = new StringValue(requestData, 6, requestData[5]);
                domain_value.Split((byte)'.').First();
                int key = Utility.Parse36Decode(domain_value.Split((byte)'.').First().UTF8());
                if (reposts.TryGetValue(key, out var result))
                {
                    await udp.SendToAsync(new ArraySegment<byte>(requestData, 0, size), result);
                }
                return;
            }
            ushort questionCount = System.Buffers.Binary.BinaryPrimitives.ReadUInt16BigEndian(requestData.AsSpan(4));
            if (questionCount == 0)
            {
                return;
            }
            var address = clientEndPoint.Address;

            var clientId = address.GetAddressBytes();

            StringValue domainName = ParseDomainName(requestData);

            var domains = ParentDomain(domainName);
            if (domainName.Span.EndsWith(Socks5Server.ProxyDomain.Span))
            {
                var indexs = new Dictionary<uint, bool>();
                var ms = HotCache.Find(new ProxySite());
                indexs.Add(0, false);
                foreach (var m in ms)
                {
                    var value3 = m.ProxyIP.UInt32() ?? 0;
                    if (value3 != 0)
                    {
                        if (indexs.TryGetValue(value3, out var value33))
                        {
                            if (m.Type.Int32() == 1)
                            {

                                if (value33 == false)
                                {
                                    indexs[value3] = true;
                                }
                            }
                        }
                        else
                        {
                            indexs[value3] = m.Type.Int32() == 1;
                        }
                    }
                }

                var proxys = indexs.Keys.ToArray();
                Array.Sort(proxys);

                var value = domainName.Slice(0, domainName.Length - Socks5Server.ProxyDomain.Length - 1);
                if (value.IsEmpty == false)
                {

                    int v = value.Span.IndexOf((byte)'-');
                    if (v == -1)
                    {
                        v = value.Span.IndexOf((byte)'.');
                    }
                    if (v > -1 && Utility.TryParse(value.Slice(v + 1).Span, 10, out var proxyId))
                    {
                        if (proxyId < proxys.Length)
                        {
                            if (indexs.TryGetValue(proxys[proxyId], out var value33))
                            {
                                if (value33)
                                {

                                    var addreses = new IPAddress[] { new IPAddress(proxys[proxyId].StringValue().Span) };//[ySite.ProxyType.Span) };

                                    BuildDnsResponse(udp, requestData, domainName, clientEndPoint, addreses);
                                    return;
                                }
                            }
                        }
                    }
                }
                BuildDnsResponse(udp, requestData, domainName, clientEndPoint);
                return;
            }
            var proxySite = HotCache.Find(new ProxySite { Domain = domainName }, "Domain", domains).OrderByDescending(d => d.Domain.Length).FirstOrDefault();
            if (proxySite != null)
            {
                var addreses = Array.Empty<IPAddress>();
                var ProxyType = proxySite.ProxyIP.UInt32() ?? 0;

                if (ProxyType != 0 && proxySite.Type.Int32() == 1)
                {

                    int value = 0;
                    if (proxySite.ProxyIP.Length > 4)
                    {
                        Utility.MD5(domainName.Span, requestData.AsSpan(400));

                        var md5 = Utility.IntParse(requestData.AsSpan(400, 16)).StringValue();
                        var query = proxySite.RecursiveQuery ?? StringValue.Empty;

                        int iplen = proxySite.ProxyIP.Length;
                        if (iplen < query.Length)// >proxySite.ProxyIP.Length)
                        {
                            query = query.Slice(0, iplen);
                        }
                        value = query.Span.IndexOf(md5.Span);
                        if (value == -1)
                        {
                            if (query.Length != iplen)
                            {
                                if (query.Length < iplen)
                                {
                                    var t = new byte[query.Length + 4];
                                    query.Span.CopyTo(t);
                                    query = new StringValue(t);
                                }
                                else
                                {
                                    query = query.Slice(0, iplen);
                                }
                                md5.Span.CopyTo(query.Span.Slice(query.Length - 4));
                            }
                            else
                            {
                                query.Span.Slice(4, query.Length - 4).CopyTo(query.Span);
                                md5.Span.CopyTo(query.Span.Slice(query.Length - 4));
                            }

                            HotCache.Put(new ProxySite
                            {
                                Domain = proxySite.Domain,
                                RecursiveQuery = query,//new StringValue(t)
                            });
                            value = ((query.Length - 4) / 4) % (proxySite.ProxyIP.Length / 4);
                        }
                        else
                        {
                            value = (value / 4) % (proxySite.ProxyIP.Length / 4);
                        }
                    }
                    addreses = new IPAddress[] { new IPAddress(proxySite.ProxyIP.Slice(value * 4, 4).Span) };


                }

                BuildDnsResponse(udp, requestData, domainName, clientEndPoint, addreses);
                return;
            }
            using (Socket client = new Socket(IterativeDNS.AddressFamily, SocketType.Dgram, ProtocolType.Udp))// new UdpClient(IterativeDNS.AddressFamily))
            {
                var timeOut = new CancellationTokenSource(5000);
                await client.SendToAsync(requestData.AsMemory(0, size), IterativeDNS, timeOut.Token);
                var res = await client.ReceiveFromAsync(requestData.AsMemory(0, size), IterativeDNS, timeOut.Token);
                await client.SendToAsync(requestData.AsMemory(0, res.ReceivedBytes), clientEndPoint, timeOut.Token);
            }

        }
        catch
        {

        }
        finally
        {
            System.Buffers.ArrayPool<byte>.Shared.Return(requestData);
        }
    }

    public static StringValue[] ParentDomain(StringValue requestData)
    {
        var domains = new List<StringValue>();
        var spn = requestData.Span;
        bool Start = true;
        for (var i = spn.Length - 1; i > 0; i--)
        {
            switch (spn[i])
            {
                case (byte)'.':
                    if (Start)
                    {
                        Start = false;
                    }
                    else
                    {
                        domains.Add(requestData.Slice(i + 1));
                    }
                    break;
            }
        }
        return domains.ToArray();
    }
    public static IPEndPoint IterativeDNS
    {
        get; set;
    } = new IPEndPoint(IPAddress.Parse("180.76.76.76"), 53);
    // 解析 DNS 请求中的域名
    public static StringValue ParseDomainName(byte[] requestData)
    {
        int index = 12;
        var size = 512;
        while (true)
        {
            byte length = requestData[index];
            index++;

            if (length == 0)
            {
                break;
            }
            else
            {
                requestData[size] = (byte)'.';
                size++;

                requestData.AsSpan(index, length).CopyTo(requestData.AsSpan(size));
                size += length;
            }
            index += length;
        }

        return new StringValue(requestData, 513, size - 513);
    }
    // private async void BuildDnsIterativeResponse(Socket udp, byte[] requestData, StringValue domainName, IPEndPoint clientEndPoint)
    // {

    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(2), (ushort)0x8180);//.CopyTo(requestData, 2); // 标志位（标准响应）
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(4), (ushort)1); // 查询数量
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(6), (ushort)0); // 应答数量
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(8), (ushort)1); // 掩码
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(10), (ushort)1); // 掩码
    //     int size = 12;

    //     // 2. 查询的域名部分
    //     size += GetDomainNameBytes(requestData.AsSpan(size), domainName);
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
    //     size += 2;
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
    //     size += 2;

    //     ushort t = 0xc000 + 12;

    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), t);
    //     size += 2;


    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 2);//
    //     size += 2;
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)1);//// 类 IN (1)
    //     size += 2;
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt32BigEndian(requestData.AsSpan(size), 10);// // TTL
    //     size += 4;
    //     var len = GetDomainNameBytes(requestData.AsSpan(size + 2), new StringValue(IterativeDNS.Address.ToString().UTF8()));

    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)4);//
    //     size += 2;
    //     ushort t2 = (ushort)(0xc000 + size);
    //     size += len;
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), t2);
    //     size += 2;

    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);//
    //     size += 2;
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)1);//// 类 IN (1)
    //     size += 2;
    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt32BigEndian(requestData.AsSpan(size), 10);// // TTL
    //     size += 4;

    //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 4);//
    //     size += 2;
    //     IterativeDNS.Address.TryWriteBytes(requestData.AsSpan(size), out var bytesWritten);
    //     size += bytesWritten;

    //     // }
    //     await udp.SendToAsync(new ArraySegment<byte>(requestData, 0, size), clientEndPoint);

    // }
    public static int BuildDnsResponse(byte[] requestData, StringValue domainName, uint tls, params IPAddress[] address)
    {
        if (address.Length == 0)
        {
            if (Addresses.Length > 1)
            {
                address = new IPAddress[] { Addresses[Random.Shared.Next(0, Addresses.Length)] };

            }
            else
            {
                address = Addresses;// new IPAddress[] { IPAddress.Loopback };
            }
        }
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(2), (ushort)0x8180);//.CopyTo(requestData, 2); // 标志位（标准响应）
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(4), (ushort)1); // 查询数量
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(6), (ushort)address.Length); // 应答数量
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(8), (ushort)0); // 掩码
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(10), (ushort)0); // 掩码
        int size = 12;

        size += GetDomainNameBytes(requestData.AsSpan(size), domainName);
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
        size += 2;
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
        size += 2;

        ushort t = 0xc000 + 12;

        foreach (var addr in address)
        {
            System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), t);
            size += 2;

            ushort recordType = 1;
            if (addr.AddressFamily == AddressFamily.InterNetworkV6)
            {
                recordType = 28;
            }

            System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), recordType);//
            size += 2;
            System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)1);//// 类 IN (1)
            size += 2;
            System.Buffers.Binary.BinaryPrimitives.WriteUInt32BigEndian(requestData.AsSpan(size), tls);// // TTL
            size += 4;

            System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)(recordType == 1 ? 4 : 16));//
            size += 2;
            addr.TryWriteBytes(requestData.AsSpan(size), out var bytesWritten);
            size += bytesWritten;
        }
        return size;
    }
    private async void BuildDnsResponse(Socket udp, byte[] requestData, StringValue domainName, IPEndPoint clientEndPoint, params IPAddress[] address)
    {

        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(2), (ushort)0x8180);//.CopyTo(requestData, 2); // 标志位（标准响应）
        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(4), (ushort)1); // 查询数量
        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(6), (ushort)this.address.Length); // 应答数量
        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(8), (ushort)0); // 掩码
        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(10), (ushort)0); // 掩码
        // int size = 12;

        // // 2. 查询的域名部分
        // size += GetDomainNameBytes(requestData.AsSpan(size), domainName);
        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
        // size += 2;
        // System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
        // size += 2;

        // ushort t = 0xc000 + 12;

        // foreach (var addr in this.address)
        // {
        //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), t);
        //     size += 2;

        //     ushort recordType = 1;
        //     if (addr.AddressFamily == AddressFamily.InterNetworkV6)
        //     {
        //         recordType = 28;
        //     }

        //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), recordType);//
        //     size += 2;
        //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)1);//// 类 IN (1)
        //     size += 2;
        //     System.Buffers.Binary.BinaryPrimitives.WriteUInt32BigEndian(requestData.AsSpan(size), 10);// // TTL
        //     size += 4;

        //     System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)(recordType == 1 ? 4 : 16));//
        //     size += 2;
        //     addr.TryWriteBytes(requestData.AsSpan(size), out var bytesWritten);
        //     size += bytesWritten;
        // }

        await udp.SendToAsync(new ArraySegment<byte>(requestData, 0, BuildDnsResponse(requestData, domainName, TLSTIME, address)), clientEndPoint);

    }



    // 将域名转换成字节数组
    public static int GetDomainNameBytes(Span<byte> requestData, StringValue domainName)
    {
        var parts = domainName.Split((byte)'.');
        //    domainNameBytes =  requestData.SequenceCompareTo new byte[domainName.Length + parts.Length];

        int index = 0;
        foreach (var part in parts)
        {
            requestData[index] = (byte)part.Length;
            part.Span.CopyTo(requestData.Slice(index + 1));
            // Array.Copy(Encoding.ASCII.GetBytes(part), 0, domainNameBytes, index + 1, part.Length);
            index += part.Length + 1;
        }
        requestData[index] = 0;

        return domainName.Length + 2;
    }
}
/*
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using UMC.Data;
using UMC.ITME.Entities;
using UMC.Net;

namespace UMC.ITME;
class DnsServer
{
    private Socket udpServer;
    // byte[] _requestData = System.Buffers.ArrayPool<byte>.Shared.Rent(512);
    static IPAddress[] _localAddress;
    static IPAddress[] LocalAddress
    {
        get
        {
            if (_localAddress == null)
            {
                var ls = new List<IPAddress>();
                foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
                {
                    if (ni.OperationalStatus == OperationalStatus.Up && ni.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                    {
                        var properties = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ip in properties.UnicastAddresses)
                        {
                            if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                                ls.Add(ip.Address);
                        }
                    }
                }
                _localAddress = ls.ToArray();
            }
            return _localAddress;
            // 获取本机所有网络接口的IP地址

        }
    }
    IPEndPoint _localEndPoint;
    SocketAsyncEventArgs _receiveEventArgs;
    public Socket Bind(int port)
    {
        // 设置本地端口
        _localEndPoint = new IPEndPoint(IPAddress.Any, port);

        udpServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        udpServer.Bind(_localEndPoint);

        // 创建接收的 SocketAsyncEventArgs
        _receiveEventArgs = new SocketAsyncEventArgs();
        _receiveEventArgs.SetBuffer(new byte[512]);//, 0, _requestData.Length);
        _receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceiveCompleted);
        // _receiveEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
        _receiveEventArgs.RemoteEndPoint = _localEndPoint;

        if (!udpServer.ReceiveFromAsync(_receiveEventArgs))
        {
            // 如果是同步完成了接收
            OnReceiveCompleted(udpServer, _receiveEventArgs);
        }
        return udpServer;
    }


    private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
    {
        // 处理接收到的数据

        if (e.BytesTransferred > 0)
        {
            ProcessDnsRequest(_responseData, e.BytesTransferred, (IPEndPoint)e.RemoteEndPoint);

            while (!udpServer.ReceiveFromAsync(e))
            {
                if (e.BytesTransferred > 0)
                {
                    Array.Copy(e.Buffer, _responseData, e.BytesTransferred);
                    ProcessDnsRequest(_responseData, e.BytesTransferred, (IPEndPoint)e.RemoteEndPoint);
                }
                else
                {
                    break;
                }
            }
        }
    }
    // 处理 UDP 请求

    private static readonly string UpstreamDnsServer = "8.8.8.8";  // Google DNS
    private async void ProcessDnsRequest(Memory<byte> reques, IPEndPoint clientEndPoint)
    {

        byte[] requestData = System.Buffers.ArrayPool<byte>.Shared.Rent(600);
        int size = reques.Length;
        reques.CopyTo(requestData);
        // Array.Copy(e.Buffer, _responseData, e.BytesTransferred);
        // 解析请求头信息
        // ushort transactionId = BitConverter.ToUInt16(requestData);
        // ushort flags = BitConverter.ToUInt16(requestData.AsSpan(2));
        try
        {
            ushort questionCount = System.Buffers.Binary.BinaryPrimitives.ReadUInt16BigEndian(requestData.AsSpan(4));
            if (questionCount == 0)
            {
                // Console.WriteLine("无查询记录，忽略该请求。");
                return;
            }

            // 提取查询的域名
            int index = 12; // 请求报文头部是 12 字节
            StringValue domainName = ParseDomainName(requestData, ref index);

            var domains = ParentDomain(domainName);
            if (domainName.Span.EndsWith(Socks5Server.ProxyDomain.Span))
            {

                BuildDnsResponse(requestData, domainName, clientEndPoint, LocalAddress.First());
                return;
            }

            if (domains.Length > 0)
            {
                if (HotCache.Find(new ProxySite { Domain = domainName }, "Domain", domains).Length > 0)
                {

                    BuildDnsResponse(requestData, domainName, clientEndPoint, LocalAddress.First());
                    return;
                }

            }
            else if (HotCache.Get(new ProxySite { Domain = domainName }) != null)
            {
                BuildDnsResponse(requestData, domainName, clientEndPoint, LocalAddress.First());
                return;
            }
            try
            {
                // Console.WriteLine(domainName);
                UdpClient client = new UdpClient("192.168.0.1", 53);
                // byte[] queryPacket = BuildDnsRequest(transactionId, domainName);
                await client.SendAsync(requestData, size);

                // 接收上游 DNS 服务器的响应
                // IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
                var res = await client.ReceiveAsync();

                client.Close();
                // return responsePacket;  // 返回响应
                await udpServer.SendToAsync(res.Buffer, clientEndPoint);//, size);
            }
            catch
            {

            }
            // UdpClient udpSender = new UdpClient();
            // BuildDnsResponse(requestData, domainName, clientEndPoint, await Dns.GetHostAddressesAsync(domainName.UTF8()).);



        }
        finally
        {
            System.Buffers.ArrayPool<byte>.Shared.Return(requestData);
        }
    }
    // private static byte[] RecursiveQuery(ushort transactionId, string domainName)
    // {
    //     try
    //     {
    //         // 向上游 DNS 服务器发送查询请求
    //         UdpClient client = new UdpClient(UpstreamDnsServer, 53);
    //         byte[] queryPacket = BuildDnsRequest(transactionId, domainName);
    //         client.SendAsync(queryPacket, queryPacket.Length);

    //         // 接收上游 DNS 服务器的响应
    //         IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
    //         byte[] responsePacket = client.ReceiveAsync(ref endPoint);

    //         client.Close();
    //         return responsePacket;  // 返回响应
    //     }
    //     catch (Exception ex)
    //     {
    //         Console.WriteLine("递归查询错误: " + ex.Message);
    //         return new byte[0];
    //     }
    // }


    // // 处理 TCP 请求
    // private static void ProcessTcpRequest(TcpClient tcpClient)
    // {
    //     try
    //     {
    //         using (NetworkStream networkStream = tcpClient.GetStream())
    //         {
    //             // 读取请求数据
    //             byte[] requestHeader = new byte[2];
    //             networkStream.Read(requestHeader, 0, 2); // 先读取事务 ID

    //             ushort transactionId = BitConverter.ToUInt16(requestHeader, 0);

    //             byte[] lengthBuffer = new byte[2];
    //             networkStream.Read(lengthBuffer, 0, 2);
    //             ushort requestLength = BitConverter.ToUInt16(lengthBuffer, 0);

    //             byte[] requestData = new byte[requestLength];
    //             networkStream.Read(requestData, 0, requestLength);

    //             // 解析 DNS 请求
    //             ushort flags = BitConverter.ToUInt16(requestData, 2);
    //             ushort questionCount = BitConverter.ToUInt16(requestData, 4);

    //             Console.WriteLine($"接收到 DNS 请求 (TCP)，事务 ID: {transactionId}, 查询数量: {questionCount}");

    //             if (questionCount == 0)
    //             {
    //                 Console.WriteLine("无查询记录，忽略该请求。");
    //                 return;
    //             }

    //             // 提取查询的域名
    //             int index = 12; // 请求报文头部是 12 字节
    //             string domainName = ParseDomainName(requestData, ref index);

    //             Console.WriteLine($"查询的域名是: {domainName}");

    //             // 生成 DNS 响应报文
    //             byte[] responseData = BuildDnsResponse(transactionId, domainName);

    //             // 向客户端发送响应
    //             byte[] responseLength = BitConverter.GetBytes((ushort)responseData.Length);
    //             networkStream.Write(responseLength, 0, 2); // 先发送响应长度
    //             networkStream.Write(responseData, 0, responseData.Length);

    //             Console.WriteLine("DNS 响应已发送 (TCP)。");
    //         }
    //     }
    //     catch (Exception ex)
    //     {
    //         Console.WriteLine("处理 TCP 请求时发生错误: " + ex.Message);
    //     }
    //     finally
    //     {
    //         tcpClient.Close();
    //     }
    // }
    private StringValue[] ParentDomain(StringValue requestData)
    {
        var domains = new List<StringValue>();
        // domains.Add(requestData);
        var spn = requestData.Span;
        bool Start = true;
        for (var i = spn.Length - 1; i > 0; i--)
        {
            switch (spn[i])
            {
                case (byte)'.':
                    if (Start)
                    {
                        Start = false;
                    }
                    else
                    {
                        domains.Add(requestData.Slice(i + 1));
                    }
                    break;
            }
        }
        return domains.ToArray();
    }
    // 解析 DNS 请求中的域名
    private StringValue ParseDomainName(byte[] requestData, ref int index)
    {
        // StringBuilder domainName = new StringBuilder();
        // int start = index + 1;
        // var span = requestData.Span;
        var size = 512;
        // var spanD= _requestData.AsSpan(512);
        while (true)
        {
            byte length = requestData[index];
            index++;

            if (length == 0)
            {
                break;
            }
            else
            {
                requestData[size] = (byte)'.';
                size++;

                requestData.AsSpan(index, length).CopyTo(requestData.AsSpan(size));
                size += length;
            }
            index += length;
        }

        return new StringValue(requestData, 513, size - 513);//.UTF8();// domainName.ToString().TrimEnd('.');
    }
    // public static string ParseDnsResponse(byte[] response)
    // {
    //     // 从响应中提取 IP 地址 (假设是 A 记录)
    //     int answerStartIndex = 12 + response[12] + 5; // 跳过查询部分和标签长度
    //     byte[] ipBytes = new byte[4];
    //     Array.Copy(response, answerStartIndex + 10, ipBytes, 0, 4); // 从响应中提取 IP 地址部分
    //     return string.Join(".", ipBytes);
    // }
    private static byte[] CreateDnsRequest(string domain)
    {
        // DNS 请求报文的构造
        byte[] requestPacket = new byte[512];
        Random rand = new Random();
        ushort transactionId = (ushort)rand.Next(0, 65535);

        // DNS 请求头部（2 字节事务ID，2 字节标志，2 字节问题数量，0 字节附加字段）
        requestPacket[0] = (byte)(transactionId >> 8);
        requestPacket[1] = (byte)(transactionId & 0xFF);
        requestPacket[2] = 0x01; // 标志：标准查询
        requestPacket[3] = 0x00;
        requestPacket[4] = 0x00; // 问题数目
        requestPacket[5] = 0x01;
        requestPacket[6] = 0x00; // 额外的记录数目
        requestPacket[7] = 0x00;

        // 域名部分：按照 DNS 协议格式将域名分割成长度和字符
        string[] domainParts = domain.Split('.');
        int offset = 12;  // 从报文头开始偏移

        foreach (var part in domainParts)
        {
            requestPacket[offset] = (byte)part.Length;  // 每个域名部分的长度
            offset++;
            byte[] domainBytes = Encoding.ASCII.GetBytes(part);
            Array.Copy(domainBytes, 0, requestPacket, offset, domainBytes.Length);
            offset += domainBytes.Length;
        }

        requestPacket[offset] = 0;  // 域名结束标志
        offset++;

        // 查询类型：A 记录查询（IPv4 地址）
        requestPacket[offset] = 0x00;
        requestPacket[offset + 1] = 0x01; // A 记录
        offset += 2;

        // 查询类：IN（Internet）
        requestPacket[offset] = 0x00;
        requestPacket[offset + 1] = 0x01; // IN 类
        offset += 2;

        return requestPacket;
    }
    private static string ParseDnsResponse(byte[] responsePacket)
    {
        // DNS 响应解析，提取 IP 地址（这里只处理最简单的 A 记录）
        if (responsePacket.Length < 12)
        {
            throw new Exception("无效的 DNS 响应");
        }

        int answerCount = (responsePacket[6] << 8) + responsePacket[7];
        int offset = 12 + (responsePacket[12] + 1 + responsePacket[13] + 1);

        for (int i = 0; i < answerCount; i++)
        {
            // 跳过域名部分
            offset += 2; // 类型
            offset += 2; // 类别
            offset += 4; // TTL

            int dataLength = (responsePacket[offset] << 8) + responsePacket[offset + 1];
            offset += 2;

            if (dataLength == 4) // A 记录 (IPv4 地址)
            {
                byte[] ipBytes = new byte[4];
                Array.Copy(responsePacket, offset, ipBytes, 0, 4);
                offset += 4;
                return string.Join(".", ipBytes);
            }
        }

        return null;
    }


    public static byte[] BuildDnsQuery(string domain)
    {
        // 交易ID (随机生成)
        Random rand = new Random();
        ushort transactionId = (ushort)rand.Next(ushort.MinValue, ushort.MaxValue);

        // DNS 查询报文头部
        byte[] query = new byte[12 + domain.Length + 2 + 4];
        int index = 0;

        // 交易 ID (2 字节)
        query[index++] = (byte)(transactionId >> 8);
        query[index++] = (byte)(transactionId & 0xFF);

        // 标志 (2 字节) - 标准查询
        query[index++] = 0x01; // 请求查询
        query[index++] = 0x00;

        // 问题数 (2 字节) - 1 个问题
        query[index++] = 0x00;
        query[index++] = 0x01;

        // 资源记录数 (2 字节) - 0
        query[index++] = 0x00;
        query[index++] = 0x00;

        // 授权资源记录数 (2 字节) - 0
        query[index++] = 0x00;
        query[index++] = 0x00;

        // 额外资源记录数 (2 字节) - 0
        query[index++] = 0x00;
        query[index++] = 0x00;

        // 域名部分
        string[] labels = domain.Split('.');
        foreach (string label in labels)
        {
            query[index++] = (byte)label.Length;
            foreach (char c in label)
            {
                query[index++] = (byte)c;
            }
        }

        // 结束符
        query[index++] = 0x00;

        // 类型字段 (2 字节) - A 记录 (IPv4)
        query[index++] = 0x00;
        query[index++] = 0x01;

        // 类字段 (2 字节) - IN 类
        query[index++] = 0x00;
        query[index++] = 0x01;

        return query;
    }
    // 构建 DNS 响应报文，支持 A、CNAME、MX、AAAA、TXT 记录
    private async void BuildDnsResponse(byte[] requestData, StringValue domainName, IPEndPoint clientEndPoint, IPAddress iPAddress)
    {
        // 1. 响应头部 (12 字节)
        // byte[] responseHeader = new byte[12];
        // BitConverter.GetBytes(transactionId).CopyTo(responseHeader, 0); // 事务 ID
        // ()
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(2), (ushort)0x8180);//.CopyTo(requestData, 2); // 标志位（标准响应）
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(4), (ushort)1); // 查询数量
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(6), 1); // 应答数量
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(8), (ushort)0); // 掩码
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(10), (ushort)0); // 掩码
        int size = 12;

        // Dns.
        // foreach (var iPAddress in IPS)
        // {
        // 2. 查询的域名部分
        size += GetDomainNameBytes(requestData.AsSpan(size), domainName);
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
        size += 2;
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), 1);
        size += 2;

        ushort t = 0xc000 + 12;

        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), t);
        size += 2;

        ushort recordType = 1;
        if (iPAddress.AddressFamily == AddressFamily.InterNetworkV6)
        {
            recordType = 28;
        }

        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), recordType);//
        size += 2;
        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)1);//// 类 IN (1)
        size += 2;
        System.Buffers.Binary.BinaryPrimitives.WriteUInt32BigEndian(requestData.AsSpan(size), 3600);// // TTL
        size += 4;

        System.Buffers.Binary.BinaryPrimitives.WriteUInt16BigEndian(requestData.AsSpan(size), (ushort)(recordType == 1 ? 4 : 16));//
        size += 2;
        iPAddress.TryWriteBytes(requestData.AsSpan(size), out var bytesWritten);
        size += bytesWritten;
        await udpServer.SendToAsync(new ArraySegment<byte>(requestData, 0, size), clientEndPoint);

    }

    // 获取记录类型，基于查询的域名（这里只是简单示范，实际可以根据需求扩展）
    // private static ushort GetRecordType(string domainName)
    // {
    //     if (domainName.EndsWith("com"))
    //     {
    //         return 1; // 返回 A 记录
    //     }
    //     else if (domainName.EndsWith("example.com"))
    //     {
    //         return 5; // 返回 CNAME 记录
    //     }
    //     else if (domainName.EndsWith("mx.com"))
    //     {
    //         return 15; // 返回 MX 记录
    //     }
    //     else if (domainName.EndsWith("ipv6.com"))
    //     {
    //         return 28; // 返回 AAAA 记录
    //     }
    //     else if (domainName.EndsWith("txt.com"))
    //     {
    //         return 16; // 返回 TXT 记录
    //     }
    //     else
    //     {
    //         return 1; // 默认返回 A 记录
    //     }
    // }

    // 将域名转换成字节数组
    private static int GetDomainNameBytes(Span<byte> requestData, StringValue domainName)
    {
        var parts = domainName.Split((byte)'.');
        //    domainNameBytes =  requestData.SequenceCompareTo new byte[domainName.Length + parts.Length];

        int index = 0;
        foreach (var part in parts)
        {
            requestData[index] = (byte)part.Length;
            part.Span.CopyTo(requestData.Slice(index + 1));
            // Array.Copy(Encoding.ASCII.GetBytes(part), 0, domainNameBytes, index + 1, part.Length);
            index += part.Length + 1;
        }
        requestData[index] = 0;

        return domainName.Length + 2;
    }
}

*/
/*
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Linq;

class DnsServer
{
    private static UdpClient udpServer;
    private static TcpListener tcpListener;
    private static IPEndPoint udpEndPoint;

    // 上游 DNS 服务器（用于递归查询）
    private static readonly string UpstreamDnsServer = "8.8.8.8";  // Google DNS

    static void Main(string[] args)
    {
        // 设置 DNS 服务端监听的端口
        int port = 53;

        // 启动 UDP 服务器
        udpServer = new UdpClient(port);
        udpEndPoint = new IPEndPoint(IPAddress.Any, port);
        Thread udpThread = new Thread(new ThreadStart(StartUdpServer));
        udpThread.Start();

        // 启动 TCP 服务器
        tcpListener = new TcpListener(IPAddress.Any, port);
        tcpListener.Start();
        Thread tcpThread = new Thread(new ThreadStart(StartTcpServer));
        tcpThread.Start();

        Console.WriteLine("DNS 服务器已启动，监听端口 53 (UDP 和 TCP)...");
    }

    // 启动 UDP 服务器
    private static void StartUdpServer()
    {
        while (true)
        {
            try
            {
                // 接收客户端的 UDP 请求
                byte[] requestData = udpServer.Receive(ref udpEndPoint);

                // 解析 DNS 请求
                ProcessDnsRequest(requestData, udpEndPoint, isRecursiveQuery: true);
            }
            catch (Exception ex)
            {
                Console.WriteLine("接收 UDP 请求时发生错误: " + ex.Message);
            }
        }
    }

    // 启动 TCP 服务器
    private static void StartTcpServer()
    {
        while (true)
        {
            try
            {
                // 等待接入的 TCP 客户端连接
                TcpClient tcpClient = tcpListener.AcceptTcpClient();
                Thread tcpClientThread = new Thread(() => ProcessTcpRequest(tcpClient));
                tcpClientThread.Start();
            }
            catch (Exception ex)
            {
                Console.WriteLine("接收 TCP 请求时发生错误: " + ex.Message);
            }
        }
    }

    // 处理 UDP 请求
    private static void ProcessDnsRequest(byte[] requestData, IPEndPoint clientEndPoint, bool isRecursiveQuery)
    {
        // 解析请求头信息
        ushort transactionId = BitConverter.ToUInt16(requestData, 0);
        ushort flags = BitConverter.ToUInt16(requestData, 2);
        ushort questionCount = BitConverter.ToUInt16(requestData, 4);

        Console.WriteLine($"接收到 DNS 请求 (UDP)，事务 ID: {transactionId}, 查询数量: {questionCount}");

        if (questionCount == 0)
        {
            Console.WriteLine("无查询记录，忽略该请求。");
            return;
        }

        // 提取查询的域名
        int index = 12; // 请求报文头部是 12 字节
        string domainName = ParseDomainName(requestData, ref index);

        Console.WriteLine($"查询的域名是: {domainName}");

        // 如果是递归查询，向上游 DNS 服务器请求
        byte[] responseData;
        if (isRecursiveQuery)
        {
            responseData = RecursiveQuery(transactionId, domainName);  // 执行递归查询
        }
        else
        {
            // 否则进行迭代查询
            responseData = IterativeQuery(transactionId, domainName);  // 执行迭代查询
        }

        // 发送响应回客户端
        udpServer.Send(responseData, responseData.Length, clientEndPoint);
        Console.WriteLine("DNS 响应已发送 (UDP)。");
    }

    // 处理 TCP 请求
    private static void ProcessTcpRequest(TcpClient tcpClient)
    {
        try
        {
            using (NetworkStream networkStream = tcpClient.GetStream())
            {
                // 读取请求数据
                byte[] requestHeader = new byte[2];
                networkStream.Read(requestHeader, 0, 2); // 先读取事务 ID

                ushort transactionId = BitConverter.ToUInt16(requestHeader, 0);

                byte[] lengthBuffer = new byte[2];
                networkStream.Read(lengthBuffer, 0, 2);
                ushort requestLength = BitConverter.ToUInt16(lengthBuffer, 0);

                byte[] requestData = new byte[requestLength];
                networkStream.Read(requestData, 0, requestLength);

                // 解析 DNS 请求
                ushort flags = BitConverter.ToUInt16(requestData, 2);
                ushort questionCount = BitConverter.ToUInt16(requestData, 4);

                Console.WriteLine($"接收到 DNS 请求 (TCP)，事务 ID: {transactionId}, 查询数量: {questionCount}");

                if (questionCount == 0)
                {
                    Console.WriteLine("无查询记录，忽略该请求。");
                    return;
                }

                // 提取查询的域名
                int index = 12; // 请求报文头部是 12 字节
                string domainName = ParseDomainName(requestData, ref index);

                Console.WriteLine($"查询的域名是: {domainName}");

                // 如果是递归查询，向上游 DNS 服务器请求
                byte[] responseData = RecursiveQuery(transactionId, domainName);  // 执行递归查询

                // 向客户端发送响应
                byte[] responseLength = BitConverter.GetBytes((ushort)responseData.Length);
                networkStream.Write(responseLength, 0, 2); // 先发送响应长度
                networkStream.Write(responseData, 0, responseData.Length);

                Console.WriteLine("DNS 响应已发送 (TCP)。");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("处理 TCP 请求时发生错误: " + ex.Message);
        }
        finally
        {
            tcpClient.Close();
        }
    }

    // 递归查询
    private static byte[] RecursiveQuery(ushort transactionId, string domainName)
    {
        try
        {
            // 向上游 DNS 服务器发送查询请求
            UdpClient client = new UdpClient(UpstreamDnsServer, 53);
            byte[] queryPacket = BuildDnsRequest(transactionId, domainName);
            client.Send(queryPacket, queryPacket.Length);

            // 接收上游 DNS 服务器的响应
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
            byte[] responsePacket = client.Receive(ref endPoint);

            client.Close();
            return responsePacket;  // 返回响应
        }
        catch (Exception ex)
        {
            Console.WriteLine("递归查询错误: " + ex.Message);
            return new byte[0];
        }
    }

    // 迭代查询（模拟）
    private static byte[] IterativeQuery(ushort transactionId, string domainName)
    {
        // 这里我们模拟返回迭代查询的中间结果
        byte[] responseHeader = new byte[12];
        BitConverter.GetBytes(transactionId).CopyTo(responseHeader, 0); // 事务 ID
        BitConverter.GetBytes((ushort)0x8180).CopyTo(responseHeader, 2); // 标志位（标准响应）
        BitConverter.GetBytes((ushort)1).CopyTo(responseHeader, 4); // 查询数量
        BitConverter.GetBytes((ushort)1).CopyTo(responseHeader, 6); // 应答数量
        BitConverter.GetBytes((ushort)0).CopyTo(responseHeader, 8); // 掩码
        BitConverter.GetBytes((ushort)0).CopyTo(responseHeader, 10); // 掩码

        byte[] domainNameBytes = GetDomainNameBytes(domainName);
        byte[] response = new byte[responseHeader.Length + domainNameBytes.Length + 16];

        responseHeader.CopyTo(response, 0);
        domainNameBytes.CopyTo(response, responseHeader.Length);

        // 模拟迭代查询的返回结果，这里只是一个简单的返回其他 DNS 服务器的地址
        string nextDnsServer = "8.8.4.4";  // 作为迭代查询的中间结果
        byte[] nextDnsServerBytes = GetDomainNameBytes(nextDnsServer);
        BitConverter.GetBytes((ushort)5).CopyTo(response, responseHeader.Length + domainNameBytes.Length); // CNAME 记录类型
        BitConverter.GetBytes((ushort)1).CopyTo(response, responseHeader.Length + domainNameBytes.Length + 2); // 类 IN (1)

        // 返回 解析 CNAME 记录
        nextDnsServerBytes.CopyTo(response, responseHeader.Length + domainNameBytes.Length + 10);

        return response;
    }

    // 解析 DNS 请求中的域名
    private static string ParseDomainName(byte[] requestData, ref int index)
    {
        StringBuilder domainName = new StringBuilder();

        while (true)
        {
            byte length = requestData[index];
            index++;

            if (length == 0)
            {
                break;
            }

            domainName.Append(Encoding.ASCII.GetString(requestData, index, length));
            domainName.Append(".");

            index += length;
        }

        return domainName.ToString().TrimEnd('.');
    }

    // 构建 DNS 请求报文
    private static byte[] BuildDnsRequest(ushort transactionId, string domainName)
    {
        byte[] requestHeader = new byte[12];
        BitConverter.GetBytes(transactionId).CopyTo(requestHeader, 0);  // 事务 ID
        BitConverter.GetBytes((ushort)0x0100).CopyTo(requestHeader, 2);  // 标志位（递归查询）
        BitConverter.GetBytes((ushort)1).CopyTo(requestHeader, 4);      // 查询数量
        BitConverter.GetBytes((ushort)0).CopyTo(requestHeader, 6);      // 应答数量
        BitConverter.GetBytes((ushort)0).CopyTo(requestHeader, 8);      // 掩码
        BitConverter.GetBytes((ushort)0).CopyTo(requestHeader, 10);     // 掩码

        byte[] domainNameBytes = GetDomainNameBytes(domainName);
        byte[] request = new byte[requestHeader.Length + domainNameBytes.Length + 4];

        requestHeader.CopyTo(request, 0);
        domainNameBytes.CopyTo(request, requestHeader.Length);

        // 请求类型 A (1)
        BitConverter.GetBytes((ushort)1).CopyTo(request, requestHeader.Length + domainNameBytes.Length); // A 记录
        BitConverter.GetBytes((ushort)1).CopyTo(request, requestHeader.Length + domainNameBytes.Length + 2); // 类 IN (1)

        return request;
    }

    // 将域名转换成字节数组
    private static byte[] GetDomainNameBytes(string domainName)
    {
        string[] parts = domainName.Split('.');
        byte[] domainNameBytes = new byte[domainName.Length + parts.Length];

        int index = 0;
        foreach (var part in parts)
        {
            domainNameBytes[index] = (byte)part.Length;
            Array.Copy(Encoding.ASCII.GetBytes(part), 0, domainNameBytes, index + 1, part.Length);
            index += part.Length + 1;
        }

        return domainNameBytes;
    }
}

*/